﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace isky.webapi
{
    public partial class CRMWebAPI
    {
        /// <summary>
        /// execute an unbound function
        /// </summary>
        /// <param name="function"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        private async Task<ExpandoObject> ExecuteFunction(string function, KeyValuePair<string, object>[] parameters = null)
        {
            await CheckAuthToken();
            var fullUrl = string.Empty;
            fullUrl = BuildFunctionActionURI(function, parameters);
            var results = await _httpClient.GetAsync(fullUrl);
            EnsureSuccessStatusCode(results);
            var data = await results.Content.ReadAsStringAsync();
            var values = JsonConvert.DeserializeObject<ExpandoObject>(data);
            return values;
        }

        /// <summary>
        /// Execute a bound function using object parameters
        /// </summary>
        /// <param name="function"></param>
        /// <param name="entityCollection"></param>
        /// <param name="entityID"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<ExpandoObject> ExecuteFunction(string function, string entityCollection, Guid entityID, object data)
        {
            List<KeyValuePair<string, object>> list = ConvertObjectToKeyValuePair(data);

            return await ExecuteFunction(function, entityCollection, entityID, list.ToArray());
        }
        /// <summary>
        /// execute an unbound function using object parameters
        /// </summary>
        /// <param name="function"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<ExpandoObject> ExecuteFunction(string function, object data = null)
        {
            List<KeyValuePair<string, object>> list = ConvertObjectToKeyValuePair(data);

            return await ExecuteFunction(function, list.ToArray());
        }

        /// <summary>
        /// Execute an Action
        /// </summary>
        /// <param name="action"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<ExpandoObject> ExecuteAction(string action, object data)
        {
            await CheckAuthToken();

            var fullUrl = string.Format("{0}{1}", _apiUrl, action);

            HttpRequestMessage request = new HttpRequestMessage(new HttpMethod("Post"), fullUrl);

            var jsonData = JsonConvert.SerializeObject(data);

            request.Content = new StringContent(jsonData, Encoding.UTF8, "application/json");

            var results = await _httpClient.SendAsync(request);

            EnsureSuccessStatusCode(results, jsonData: jsonData);

            var resultData = await results.Content.ReadAsStringAsync();
            var values = JsonConvert.DeserializeObject<ExpandoObject>(resultData);
            return values;
        }
        /// <summary>
        /// Execute a bound action
        /// </summary>
        /// <param name="action"></param>
        /// <param name="entityCollection"></param>
        /// <param name="entityID"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<ExpandoObject> ExecuteAction(string action, string entityCollection, Guid entityID, object data)
        {
            return await ExecuteAction(string.Format("{0}({1})/{2}", entityCollection, entityID.ToString(), action), data);
        }

    }
}
